<div class="content">

  <h1>Configuration</h1>

  <section>
    <p class="wide">
      Upgrading to 5.0.0? Read the <a [routerLink]="['/migrate500']" simplePageScroll href="#navigation">migration notes</a>.
    </p>
  </section>

    <section>
      <p class="wide">
        Simple Java Mail provides full configuration through <strong>programmatic API</strong> as well as <strong>system variables</strong>, <strong>environment variables</strong> and <strong>properties files</strong> (including Spring).
      </p>
    </section>
    <section class="introduction">
    <div class="view">
      <p>
        The Java API and config files complement each other. If you provide the overlapping configuration, the programmatic API takes priority, overriding system and environment values, overriding property values.
      </p>
    </div>
    <div class="side">
      <p>
        Central to configuring Simple Java Mail is the <strong>MailerBuilder</strong>. As the library grew maintaining all the constructors and setters proved unwieldy and so it moved to a completely <a href="https://martinfowler.com/bliki/FluentInterface.html">builder based fluent API</a> which produces a largely immutable <code class="inline">Mailer</code> instance.
      </p>
      <p>
        Second, there is the <strong>ConfigLoader</strong>, which contains all the preconfigured defaults read initially from <em>.properties</em> files. It contains programmatic API to clear, add or replace default values.
      </p>
    </div>
    </section>

  <section class="toc">
    <ul>
      <li><a simplePageScroll href="#section-transport-strategies">Transport strategies</a></li>
      <li><a simplePageScroll href="#section-transport-strategy-smtp" class="indent">TransportStrategy.SMTP</a></li>
      <li><a simplePageScroll href="#section-transport-strategy-smtps" class="indent">TransportStrategy.SMTPS</a></li>
      <li><a simplePageScroll href="#section-transport-strategy-tls" class="indent">TransportStrategy.SMTP_TLS</a></li>
      <li><a simplePageScroll href="#section-programmatic-api-common">Programmatic API - common settings</a></li>
      <li><a simplePageScroll href="#section-programmatic-api-other">Programmatic API - other settings</a></li>
      <li><a simplePageScroll href="#section-config-properties">Properties files</a></li>
      <li><a simplePageScroll href="#section-combine-config">Combining both for multiple environments</a></li>
      <li><a simplePageScroll href="#section-spring-support">Spring support</a></li>
    </ul>
  </section>


  <a href="#section-transport-strategies" id="section-transport-strategies" class="section-link h2">&sect;</a>
  <h2>Transport strategies</h2>

  <section>
    <div>
      <p class="wide">
        Although Simple Java Mail started out as a library to help produce RFC-anatomically correct emails, one of its
        primary drivers now is to simplify configuration, using <em>transport strategies</em>.
      </p>
      <p class="wide">
        There are three strategies: <code class="inline">TransportStrategy.SMTP</code>,
        <code class="inline">TransportStrategy.SMTPS</code> and <code class="inline">TransportStrategy.SMTP_TLS</code>.
      </p>
      <p>Let's quickly review them one-by-one.</p>
    </div>
  </section>


  <a href="#section-transport-strategy-smtp" id="section-transport-strategy-smtp" class="section-link h3">&sect;</a>
  <h3>TransportStrategy.SMTP</h3>

  <section>
    <div class="view">
      <p>
        This transport strategy falls back to plaintext when a mail server does not indicate support for
        STARTTLS. Additionally, even if a TLS session is negotiated, <strong>server certificates are not validated in
        any way</strong>.
      </p>
    </div>
    <div class="side">
<pre><code>
MailerBuilder.withTransportStrategy(TransportStrategy.SMTP);

// or through property defaults, skipping builder API:
simplejavamail.transportstrategy=SMTP
Mailer mailer = MailerBuilder.buildMailer();
</code></pre>
    </div>
  </section>
  <section>
    <div>
      <p class="wide">
        Furthermore, this transport strategy only offers protection against passive network eavesdroppers when the mail server
        indicates support for STARTTLS. Active network attackers can trivially bypass the encryption 1) by tampering with
        the STARTTLS indicator, 2) by presenting a self-signed certificate, 3) by presenting a certificate issued by an
        untrusted certificate authority; or 4) by presenting a certificate that was issued by a valid certificate
        authority to a domain other than the mail server's.
      </p>
      <p class="wide">
        For proper mail transport encryption, use <code class="inline">TransportStrategy.SMTPS</code> or <code class="inline">TransportStrategy.SMTP_TLS</code>.
      </p>
    </div>
  </section>
  <section>
    <div class="view">
      <p>
        To disable opportunistic TLS and revert back to the legacy SMTP_PLAIN behavior prior to 5.0.0
        (not recommended), you can turn it off programmatically or by setting the property
        <code class="inline">simplejavamail.opportunistic.tls</code>.
      </p>
    </div>
    <div class="side">
      <pre><code>
TransportStrategy.SMTP.setOpportunisticTLS(false);
MailerBuilder.withTransportStrategy(TransportStrategy.SMTP);
// or as property:
simplejavamail.opportunistic.tls=false
</code></pre>
    </div>
  </section>


  <a href="#section-transport-strategy-smtps" id="section-transport-strategy-smtps" class="section-link h3">&sect;</a>
  <h3>TransportStrategy.SMTPS</h3>

  <section>
    <div class="view">
      <p>SMTP entirely encapsulated by TLS. Commonly known as SMTPS.</p>
      <p>
        Strict validation of server certificates is enabled. Server certificates must be issued <br />
        1) by a certificate authority in the system trust store; and <br />
        2) to a subject matching the identity of the remote SMTP server.
      </p>
    </div>
    <div class="side">
<pre><code>
MailerBuilder.withTransportStrategy(TransportStrategy.SMTPS);

// or through property defaults, skipping builder API:
simplejavamail.transportstrategy=SMTPS
Mailer mailer = MailerBuilder.buildMailer();
</code></pre>
    </div>
  </section>


  <a href="#section-transport-strategy-tls" id="section-transport-strategy-tls" class="section-link h3">&sect;</a>
  <h3>TransportStrategy.SMTP_TLS</h3>

  <section>
    <div class="view">
      <p>Plaintext SMTP with a mandatory, authenticated STARTTLS upgrade.</p>
      <p>
        Strict validation of server certificates is enabled. Server certificates must be issued <br/>
        1) by a certificate authority in the system trust store; and <br/>
        2) to a subject matching the identity of the remote SMTP server.
      </p>
    </div>
    <div class="side">
<pre><code>
MailerBuilder.withTransportStrategy(TransportStrategy.SMTP_TLS);

// or through property defaults, skipping builder API:
simplejavamail.transportstrategy=SMTP_TLS
Mailer mailer = MailerBuilder.buildMailer();
</code></pre>
    </div>
  </section>
  <section>
    <div>
      <p class="wide">
        To quote FastMail on the <a href="https://www.fastmail.com/help/technical/ssltlsstarttls.html">differences between SSL and TLS</a>:
      </p>
      <blockquote>
        <p class="wide">
          <strong>SSL and TLS</strong> both provide a way to encrypt a communication channel between two computers (e.g. your computer
          and our server). TLS is the successor to SSL and the terms SSL and TLS are used interchangeably unless you're
          referring to a specific version of the protocol.
        </p>
      </blockquote>
      <blockquote>
        <p class="wide">
          The ordering of protocols in terms of oldest to newest is: SSL v2, SSL v3, TLS v1.0, TLS v1.1, TLS v1.2, TLS v1.3 (currently proposed).
        </p>
      </blockquote>
    </div>
  </section>


  <a href="#section-programmatic-api-common" id="section-programmatic-api-common" class="section-link h2">&sect;</a>
  <h2>Programmatic API - common settings</h2>

  <section>
    <div>
      <p>
        Everything can be configured through the java API. Specifically the builders are the entry point to creating Mailers and Emails and everything can be configured
        through them.
      </p>
    </div>

    <div>
<pre><code class="small">// start with a builder
MailerBuilder.withSMTPServer("smtp.host.com", 25, "username", "password");
// or
MailerBuilder
  .withSMTPServerHost("smtp.host.com")
  .withSMTPServerPort(25)
  .withSMTPUsername("username")
  .withSMTPPassword("password");
</code></pre>
      <pre><code class="small">
// you can even leave out some details for an anonymous SMTP server
MailerBuilder.withSMTPServer("smtp.host.com", 25);
// or
MailerBuilder
  .withSMTPServerHost("smtp.host.com")
  .withSMTPServerPort(25);

// adding the transport strategy...
currentMailerBuilder.withTransportStrategy(TransportStrategy.SMTP_TLS)

// or instead adding anonymous proxy configuration
currentMailerBuilder.withProxy("proxy.host.com", 1080);
// or
currentMailerBuilder
  .withProxyHost("smtp.host.com")
  .withProxyPort(25);

// or authenticated proxy
currentMailerBuilder
  .withProxy("proxy.host.com", 1080, "proxy username", "proxy password");
// or
currentMailerBuilder
  .withProxyHost("smtp.host.com")
  .withProxyPort(25)
  .withProxyUsername(25)
  .withProxyPassword(25);
</code></pre>
      <pre><code class="small">
// anonymous smtp + anonymous proxy + default SMTP protocol strategy
currentMailerBuilder
        .withSMTPHost("smtp.host.com").withSMTPServerPort(25)
        .withProxyHost("proxy.host.com").withSMTPPort(1080);
</code></pre>
      <pre><code class="small">
// configure everything!
MailerBuilder
        .withSMTPHost("smtp.host.com", 587, "user@host.com", "password")
        .withTransportStrategy(TransportStrategy.SMTP_TLS);
        .withProxyHost("socksproxy.host.com", 1080, "proxy user", "proxy password");
        .buildMailer()
        .sendMail(email);
</code></pre>
      <pre><code class="small">
// preconfigured Session?
MailerBuilder.usingSession(session);

// preconfigured but you need anonymous proxy?
MailerBuilder
        .usingSession(session)
        .withProxyHost("socksproxy.host.com", 1080);

// preconfigured but you need authenticated proxy?
MailerBuilder
        .usingSession(session)
        .withProxyHost("socksproxy.host.com", 1080, "proxy user", "proxy password");
</code></pre>
    </div>
  </section>


  <a href="#section-programmatic-api-other" id="section-programmatic-api-other" class="section-link h3">&sect;</a>
  <h3>Programmatic API - other settings</h3>

  <section>
    <div class="view">
      <p>
        Aside from transport strategy, SMTP and Proxy server details, there are a few other more generic settings.
      </p>
    </div>

    <div class="side">
      <pre><code class="small">// make the underlying javax.mail produce more logging
MailerBuilder.withDebugLogging(true);
</code></pre>
      <pre><code class="small">// skip actually sending email, just log it
currentMailerBuilder.withTransportModeLoggingOnly(true);
</code></pre>
      <pre><code class="small">
// change email validation strategy
currentMailerBuilder.withEmailAddressCriteria(EmailAddressCriteria.DEFAULT);
currentMailerBuilder.withEmailAddressCriteria(EmailAddressCriteria.RFC_COMPLIANT);
currentMailerBuilder.withEmailAddressCriteria(EnumSet
       .of(ALLOW_QUOTED_IDENTIFIERS, ALLOW_PARENS_IN_LOCALPART));

// reset to default RFC compliant checks:
currentMailerBuilder.resetmailAddressCriteria();
// deactivate email validation completely:
currentMailerBuilder.clearEmailAddressCriteria();
</code></pre>
<pre><code class="small">
// change SOCKS5 bridge port in case of authenticated proxy
currentMailerBuilder.withProxyBridgePort(1081); // always localhost
</code></pre>
<pre><code class="small">
// set custom properties
currentMailerBuilder.withProperties(new Properties());
currentMailerBuilder.withProperties(new HashMap());
currentMailerBuilder.withProperty("mail.smtp.sendpartial", true);

// or directly modify the internal Session instance:
mailer.getSession().getProperties().setProperty("mail.smtp.sendpartial", true);
</code></pre>
<pre><code class="small">
// trust all hosts for SSL connections, don't validate keys
currentMailerBuilder.trustingAllSSLHosts(true);
</code></pre>
<pre><code class="small">
// white list hosts for SSL connections, don't validate keys for these
currentMailerBuilder.trustingSSLHosts("a", "b", "c", ...);
// or clearing them
currentMailerBuilder.clearTrustedSSLHosts();
</code></pre>
<pre><code class="small">// change the pool size (default 10) for concurrent threads, each sending an email
currentMailerBuilder.withThreadPoolSize(3);
</code></pre>
      <pre><code class="small">// change the session timeout (affects socket connect-, read- and write timeouts)
currentMailerBuilder.withSessionTimeout(10 * 1000); // 10 seconds for quick disconnect
</code></pre>
    </div>
  </section>


  <a href="#section-config-properties" id="section-config-properties" class="section-link h2">&sect;</a>
  <h2>Properties files</h2>

  <section>
    <div class="view">
      <p>
        With properties files you can define defaults and overrides. You can also provide overriding value by defining system variables.
      </p>
      <p>
        Simple Java Mail will automatically load properties from <code class="inline">simplejavamail.properties</code>, if available on the classpath.
        Alternatively, you can manually load additional properties files in a number of ways.
      </p>
      <p>
        Properties are loaded in order of priority from high to low:
      </p>
      <ol class="indent">
        <li>Programmatic values</li>
        <li>System variables</li>
        <li>Environment variables</li>
        <li>Properties from config files</li>
      </ol>
    </div>

    <div class="side">
<pre><code class="small">ConfigLoader.loadProperties("overrides-on-classpath.properties", /* addProperties = */ true);
ConfigLoader.loadProperties(new File("d:/replace-from-environment.properties"), /* addProperties = */ false);
ConfigLoader.loadProperties(usingMyOwnInputStream, addProperties);
ConfigLoader.loadProperties(usingMyOwnPropertiesObject, addProperties);
</code></pre>
      This clears everything:
      <pre><code class="small">ConfigLoader.loadProperties(new Properties(), /* addProperties = */ false);
</code></pre>
    </div>
  </section>

  <a href="#section-available-properties" id="section-available-properties" class="section-link h3">&sect;</a>
  <h3>Available properties</h3>

  <section>
    <div class="view">
      <p>
        Almost everything can be set as a default property. This way you can easily configure environments without changing the code.
      </p>
    </div>

    <div class="side">
<pre><code class="language-properties">simplejavamail.javaxmail.debug=true
simplejavamail.transportstrategy=SMTPS
simplejavamail.smtp.host=smtp.default.com
simplejavamail.smtp.port=25
simplejavamail.smtp.username=username
simplejavamail.smtp.password=password
simplejavamail.proxy.host=proxy.default.com
simplejavamail.proxy.port=1080
simplejavamail.proxy.username=username proxy
simplejavamail.proxy.password=password proxy
simplejavamail.proxy.socks5bridge.port=1081
simplejavamail.defaults.subject=Sweet News
simplejavamail.defaults.from.name=From Default
simplejavamail.defaults.from.address=from@default.com
simplejavamail.defaults.replyto.name=Reply-To Default
simplejavamail.defaults.replyto.address=reply-to@default.com
simplejavamail.defaults.to.name=To Default
simplejavamail.defaults.to.address=to@default.com
simplejavamail.defaults.cc.name=CC Default
simplejavamail.defaults.cc.address=cc@default.com
simplejavamail.defaults.bcc.name=
simplejavamail.defaults.bcc.address=bcc1@default.com;bcc2@default.com
simplejavamail.defaults.poolsize=10
simplejavamail.defaults.sessiontimeoutmillis=60000
simplejavamail.transport.mode.logging.only=true
simplejavamail.opportunistic.tls=false
</code></pre>
    </div>
  </section>

  <a href="#section-combine-config" id="section-combine-config" class="section-link h2">&sect;</a>
  <h2>Combining both for multiple environments</h2>

  <section>
    <div>
      <p>
        Let's set up configuration for a <strong>test</strong>, <strong>acceptance</strong> and <strong>production</strong> environment.
      </p>
      <h3>Properties for the environments</h3>
    </div>
    <div>
<pre><code class="language-properties small">#global default properties (simplejavamail.properties on classpath)

    # anonoymous SMTP inside 'safe' DMZ
    simplejavamail.smtp.host=dmz.smtp.candyshop.com
    simplejavamail.smtp.port=25

    # default sender and reply-to address
    simplejavamail.defaults.from.name=The Candy App
    simplejavamail.defaults.from.address=candyapp@candystore.com
    simplejavamail.defaults.replyto.name=Candystore Helpdesk
    simplejavamail.defaults.replyto.address=helpdesk@candystore.com
</code></pre>
<pre><code class="language-properties small">#overrides from TEST and UAT .../config/candystore/simplejavamail.properties

    # always send a copy to test archive
    simplejavamail.defaults.bcc.name=Archive TST UAT
    simplejavamail.defaults.bcc.address=test-archive@candyshop.com
</code></pre>
<pre><code class="language-properties small">#overrides from PRODUCTION .../config/candystore/simplejavamail.properties

    # always send a copy to production archive
    simplejavamail.defaults.bcc.name=Archive PRODUCTION
    simplejavamail.defaults.bcc.address=prod-archive@candyshop.com

    # smtp server in production is protected
    simplejavamail.smtp.username=creamcake
    simplejavamail.smtp.password=crusty_l0llyp0p

    # sending mails in production must go through proxy
    simplejavamail.proxy.host=proxy.candyshop.com
    simplejavamail.proxy.port=1080
    simplejavamail.proxy.username=candyman
    simplejavamail.proxy.password=I has the sugarcanes!!1!
</code></pre>
    </div>

    <h3>Now for the programmatic part</h3>

    <div>
<pre><code>// simplejavamail.properties is automatically loaded

// assume that every environment provides its own property file
ConfigLoader.loadProperties(new File(".../config/candystore/simplejavamail.properties"));
</code></pre>
<pre><code>
// see if we need to do some specific override for some reason
if (someSpecialCondition) {{ '{' }}
  ConfigLoader.loadProperties("special-override.properties", true);
{{ '}' }}
</code></pre>
<pre><code>
// or maybe we want to ditch all defaults and trust someone else's config completely
if (ditchOwnAndTrustOtherSource) {{ '{' }}
  ConfigLoader.loadProperties(someFileOrInputSource, false);
{{ '}' }}
</code></pre>
<pre><code>
// maybe the config service has something?
ConfigLoader.loadProperties(socket.getInpuStream(), true);
// or you have your own Properties source?
ConfigLoader.loadProperties(myOwnProperties, true);
</code></pre>

      <p>
        Maybe we want to connect slightly different for some reason:
      </p>

<pre><code>// override only the port and connection type, leave everything else to config files
Mailer mailer = MailerBuilder
                  .withSMTPPort(587)
                  .withTransportStrategy(TransportStrategy.SMTP_TLS)
                  .buildMailer();
</code></pre>
    </div>
  </section>


  <a href="#section-spring-support" id="section-spring-support" class="section-link h2">&sect;</a>
  <h2>Spring support</h2>

  <section>
    <div class="view">
      <p>
        Everything can be configured through Spring properties, allowing for robust profile-based configuration.
      </p>
      <p>
        By importing the Spring support bean from Simple Java Mail, whatever properties are provided through Spring are then transfered to Simple Java Mail
        using the ConfigLoader. It will add or overwrite whatever properties have been loaded before that (including the regular simplejavamail.properties).
      </p>
      <p>Here's a sample configuration using Java style configuration.</p>
    </div>

    <div class="side">
      Loading Spring support and obtaining default Mailer instance:
<pre><code class="small">@Component // or @Configuration etc.
@Import(SimpleJavaMailSpringSupport.class)
public class YourEmailService {{ '{' }}

    @Autowired // or roll your own, as long as SimpleJavaMailSpringSupport is processed first
    private Mailer mailer;

{{ '}' }}
</code></pre>
      Then when you have profile based configuration (for example <code>default</code> and <code>production</code>):
      <pre><code class="language-properties small">#application.properties
simplejavamail.javaxmail.debug=true
simplejavamail.smtp.host=smtp.host
simplejavamail.smtp.port=25
simplejavamail.transportstrategy=SMTP
</code></pre>
      <pre><code class="language-properties small">#application-production.properties
simplejavamail.javaxmail.debug=false
simplejavamail.smtp.host=smtp.production.host
simplejavamail.smtp.port=443
simplejavamail.transportstrategy=SMTPS
simplejavamail.smtp.username=&lt;username&gt;
simplejavamail.smtp.password=&lt;password&gt;
simplejavamail.proxy.username=&lt;proxy_username&gt;
simplejavamail.proxy.password=&lt;proxy_password&gt;
</code></pre>
    </div>
  </section>

</div>
